﻿#include "WRWorkMainWindow.h"
#include "Runtime/WRWorkMainCommandActivator.h"
#include "Runtime/WRWorkMainGuiPartActivator.h"

#include <QMenu>
#include <QAction>
#include <QMenuBar>
#include <QToolBar>
#include <QSettings>
#include <QDockWidget>
#include <QCloseEvent>
#include <QMessageBox>

//初始化工作主行为。
WRWorkMainAction::WRWorkMainAction(WRWorkMainWindow* window, const WRWorkMainActionEntry& config)
    : m_config(config), m_window(window)
{
    m_target = 0;
    m_menuItem = 0;
    m_toolItem = 0;
}
//释放当前对象所占用的相关资源。
WRWorkMainAction::~WRWorkMainAction(void)
{
    if (m_config.kind() == WRWorkMainActionEntry::Command)
    {
        WRWorkMainCommand* cmd = static_cast<WRWorkMainCommand*>(m_target);
        if (cmd)
        {
            delete cmd;
        }
    }
}
//执行初始化处理。
void WRWorkMainAction::initialize(QMenu* menu)
{
    m_menuItem = menu->addAction(m_config.icon(), m_config.title(), this, SLOT(trigger()));
    m_menuItem->setObjectName(m_config.name());
    m_menuItem->setToolTip(m_config.description());
}
//执行初始化处理。
void WRWorkMainAction::initialize(QToolBar* tool)
{
    m_toolItem = tool->addAction(m_config.icon(), m_config.title(), this, SLOT(trigger()));
    m_toolItem->setObjectName(m_config.name());
    m_toolItem->setIconText(m_config.title());
    m_toolItem->setToolTip(m_config.description());
}

//创建界面部件。
WRWorkMainGuiPart* WRWorkMainAction::newGuiPart(void)
{
    if (m_config.kind() == WRWorkMainActionEntry::GuiPart)
    {
        WRWorkMainGuiPart* part = static_cast<WRWorkMainGuiPart*>(m_target);
        if (!part)
        {
            WRWorkMainGuiPartActivator* activator = static_cast<WRWorkMainGuiPartActivator*>(m_config.activator());
            part = activator->create(m_config.initParams());
            m_target = part;
        }
        return part;
    }
    return 0;
}

//触发处理事件。
void WRWorkMainAction::trigger(void)
{
    if (m_config.kind() == WRWorkMainActionEntry::Command)
    {
        WRWorkMainCommand* cmd = static_cast<WRWorkMainCommand*>(m_target);
        if (!cmd)
        {
            WRWorkMainCommandActivator* activator = static_cast<WRWorkMainCommandActivator*>(m_config.activator());
            cmd = activator->create(m_config.initParams());
            m_target = cmd;
        }
        cmd->execute(m_window, m_menuItem, m_toolItem);
    }
    else
    {
        WRWorkMainGuiPart* part = static_cast<WRWorkMainGuiPart*>(m_target);
        QDockWidget* widget = qobject_cast<QDockWidget*>(part->parent());
        widget->setVisible(true);
        if (widget->isFloating())
        {
            widget->activateWindow();
        }
        else
        {
            widget->raise();
            widget->setFocus();
        }
    }
}

//初始化主窗体。
WRWorkMainWindow::WRWorkMainWindow(const WRWorkGuiConfig& config, const WRObjRef<WRWorkDaemon>& daemon)
{
    //设置窗体基本属性
    setWindowIcon(config.icon());
    setObjectName(config.name());
    setWindowTitle(config.title());
    setWindowState(Qt::WindowMaximized | Qt::WindowActive);
    setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks);
    //
    //根据菜单配置创建菜单栏和工具栏
    QList<WRWorkMainAction*> actions;
    QMenuBar* menuBar = new QMenuBar();
    const WRArray<WRWorkMainActionClass>& actionClasses = config.actions();
    for(WRu i = 0; i < actionClasses.count(); ++i)
    {
        const WRWorkMainActionClass& actionClass = actionClasses[i];

        QMenu* menu = menuBar->addMenu(actionClass.title());
        menu->setObjectName(actionClass.name());
        menu->setToolTip(actionClass.description());

        QToolBar* toolBar = new QToolBar(actionClass.title());
        toolBar->setObjectName(actionClass.name());
        toolBar->setToolTip(actionClass.description());
        toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);

        const WRArray<WRWorkMainActionGroup> actionGroups = actionClass.groups();
        for(WRu j = 0; j < actionGroups.count(); ++j)
        {
            const WRWorkMainActionGroup& actionGroup = actionGroups[j];            
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
            QAction* section = menu->addSection(actionGroup.title());
            section->setObjectName(actionGroup.name());
            section->setToolTip(actionGroup.description());      
#endif
            if (j != 0)
            {
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
                menu->addSeparator();
#endif
                toolBar->addSeparator();
            }
            const WRArray<WRWorkMainActionEntry> actionEntries = actionGroup.entries();
            for(WRu k = 0; k < actionEntries.count(); ++k)
            {
                const WRWorkMainActionEntry& actionEntry = actionEntries[k];
                WRWorkMainAction* action = new WRWorkMainAction(this, actionEntry);
                action->initialize(menu);
                action->initialize(toolBar);
                actions.append(action);
            }
        }
        addToolBar(toolBar);
    }
    setMenuBar(menuBar);
    m_actions = actions;
    //界面部件相应处理
    for(WRu i = 0; i < m_actions.count(); ++i)
    {
        WRWorkMainAction* action = actions[(int)i];
        WRWorkMainGuiPart* part = action->newGuiPart();
        if (part)
        {
            QDockWidget* widget = new QDockWidget(action->title(), this);
            widget->setObjectName(action->name());
            widget->setToolTip(action->description());
            widget->setWindowIcon(action->icon());
            widget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
            widget->setFloating(true);
            widget->move(0, 0);
            widget->setVisible(false);
            widget->setWidget(part);
            addDockWidget(Qt::LeftDockWidgetArea, widget);
            part->init(daemon);
            QObject::connect(widget, SIGNAL(visibilityChanged(bool)), this, SLOT(onDockVisibilityChanged(bool)));
        }
    }
    //
    QSettings settings(QStringLiteral("cyvation"), objectName());
    restoreGeometry(settings.value("geometry").toByteArray());
    restoreState(settings.value("windowState").toByteArray());
}
//释放当前对象所占用的相关资源。
WRWorkMainWindow::~WRWorkMainWindow()
{
    for(WRu i = 0; i < m_actions.count(); ++i)
    {
        WRWorkMainAction* action = m_actions[i];
        delete action;
    }
}

//处理关闭事件。
void WRWorkMainWindow::closeEvent(QCloseEvent *e)
{
    QMainWindow::closeEvent(e);

    QMessageBox::StandardButton result = QMessageBox::question(this, QStringLiteral("操作确认"), QStringLiteral("确定退出“%1”？").arg(windowTitle()), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
    if (result != QMessageBox::Yes && result != QMessageBox::Ok)
    {
        e->ignore();
    }
    else
    {
        QSettings settings(QStringLiteral("cyvation"), objectName());
        settings.setValue("geometry", saveGeometry());
        settings.setValue("windowState", saveState());
    }
}

//当停靠可视性改变后调用此方法。
void WRWorkMainWindow::onDockVisibilityChanged(bool visible)
{
    QDockWidget* widget = qobject_cast<QDockWidget*>(sender());
    if (widget)
    {
        WRWorkMainGuiPart* part = qobject_cast<WRWorkMainGuiPart*>(widget->widget());
        if (part)
        {
            part->status(visible);
        }
    }
}

//获取推荐尺寸。
QSize WRWorkMainWindow::sizeHint() const
{
    return QSize(960, 600);
}
